#!/bin/bash
set -eo pipefail

# ================= 配置区 =================
PROJECT_ROOT="$(cd "$(dirname "$0")"; pwd)"
FRONTEND_DIR="${PROJECT_ROOT}/frontend/forum/src"
BACKEND_DIR="${PROJECT_ROOT}/backend/src"
CONFIG_FILE="${PROJECT_ROOT}/frontend/forum/public/config.json"

# ================= 样式定义 =================
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BOLD='\033[1m'
RESET='\033[0m'

# ================= 工具函数 =================
info() { echo -e "${BOLD}🌀 ${1}${RESET}"; }
success() { echo -e "${GREEN}✅ ${1}${RESET}"; }
warning() { echo -e "${YELLOW}⚠️  ${1}${RESET}"; }
error() { echo -e "${RED}❌ ${1}${RESET}" >&2; }

# ================= 系统检测 =================
detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS_TYPE="${ID}"
    else
        OS_TYPE=$(uname -s | tr '[:upper:]' '[:lower:]')
    fi

    case $OS_TYPE in
        ubuntu|debian|linuxmint) echo "debian";;
        centos|rhel|fedora|amzn) echo "rhel";;
        *) echo "unknown";;
    esac
}

# ================= 包管理函数 =================
install_package() {
    local pkg=$1
    case $(detect_os) in
        debian)
            sudo apt-get -qq update >/dev/null
            sudo DEBIAN_FRONTEND=noninteractive apt-get -qq install -y "$pkg"
            ;;
        rhel)
            sudo yum -q makecache >/dev/null
            sudo yum -q install -y "$pkg"
            ;;
        *)
            error "不支持的Linux发行版"
            return 1
            ;;
    esac
}

# ================= Node.js处理器 =================
ensure_curl() {
    if ! command -v curl &> /dev/null; then
        info "安装curl工具..."
        install_package curl || {
            error "curl安装失败，请手动安装后重试"
            exit 1
        }
    fi
}

ensure_npm() {
    if ! command -v npm &> /dev/null; then
        warning "npm未找到，尝试安装基础Node.js环境..."
        install_package nodejs && install_package npm || {
            error "Node.js基础环境安装失败"
            exit 1
        }
    fi
}

install_n_tool() {
    info "安装n版本管理工具..."
    sudo npm install -g n 2>&1 | while IFS= read -r line; do 
        echo -e "${BOLD}   [n安装] ${line}${RESET}"
    done
    
    sudo mkdir -p /usr/local/n /usr/local/{bin,lib,share}
    sudo chown -R $(whoami) /usr/local/n /usr/local/{bin,lib,share} 2>/dev/null || true
}

install_nodejs_with_n() {
    info "通过n安装稳定版Node.js..."
    if sudo n stable 2>&1 | tee /tmp/n-install.log; then
        export PATH="/usr/local/bin:$PATH"
        NEW_VERSION=$(node -v)
        success "Node.js ${NEW_VERSION} 安装成功，路径：$(which node)"
    else
        error "安装失败，日志详见 /tmp/n-install.log"
        exit 1
    fi
}

check_nodejs() {
    info "检查Node.js环境..."
    
    if ! command -v node &> /dev/null; then
        warning "Node.js未安装，开始自动化安装流程..."
        ensure_curl
        ensure_npm
        install_n_tool
        install_nodejs_with_n
        return
    fi

    CURRENT_VERSION=$(node -v | cut -d. -f1 | tr -d 'v')
    if [ $CURRENT_VERSION -lt 16 ]; then
        warning "当前Node.js版本v${CURRENT_VERSION}过低，开始版本升级..."
        ensure_npm
        install_n_tool
        install_nodejs_with_n
    else
        success "Node.js版本符合要求（v${CURRENT_VERSION}）"
    fi
}

# ================= 依赖处理器 =================
show_manual_guide() {
    echo -e "\n${BOLD}手动安装指南：${RESET}"
    case $(detect_os) in
        debian)
            echo "Debian/Ubuntu:"
            echo "  sudo apt-get install -y make g++ libsqlite3-dev libargon2-dev"
            ;;
        rhel)
            echo "CentOS/RHEL:"
            echo "  sudo yum install -y make gcc-c++ sqlite-devel libargon2-devel"
            ;;
    esac
    echo -e "\n官方下载："
    echo "• Node.js: https://nodejs.org"
    echo "• SQLite:  https://sqlite.org/download"
    echo "• Argon2:  https://github.com/P-H-C/phc-winner-argon2"
}

check_dependency() {
    local name=$1 check_cmd=$2 installer=$3
    
    if ! eval "$check_cmd" >/dev/null 2>&1; then
        warning "依赖缺失: $name"
        read -rp "是否尝试自动安装？[Y/n] " answer
        case "$answer" in
            [Nn]*) 
                show_manual_guide
                exit 1
                ;;
            *)
                if ! $installer "$name"; then
                    error "安装失败: $name"
                    show_manual_guide
                    exit 1
                fi
                ;;
        esac
    fi
}

# ================= 安装处理器 =================
install_system_pkg() {
    declare -A pkg_map=(
        ["make:debian"]="make"
        ["make:rhel"]="make"
        ["g++:debian"]="g++"
        ["g++:rhel"]="gcc-c++"
        ["sqlite3:debian"]="libsqlite3-dev"
        ["sqlite3:rhel"]="sqlite-devel"
        ["argon2:debian"]="libargon2-dev"
        ["argon2:rhel"]="libargon2-devel"
    )
    
    local os_type=$(detect_os)
    local pkg_key="$1:$os_type"
    
    if [ -z "${pkg_map[$pkg_key]}" ]; then
        error "不支持的包: $1"
        return 1
    fi
    
    info "正在安装: ${pkg_map[$pkg_key]}"
    install_package "${pkg_map[$pkg_key]}"
}

# ================= 依赖队列 =================
declare -a DEPENDENCIES=(
    "Node.js>=16.x:check_nodejs"
    "make:command -v make:install_system_pkg make"
    "g++:command -v g++:install_system_pkg g++"
    "SQLite3开发库:pkg-config --exists sqlite3:install_system_pkg sqlite3"
    "Argon2开发库:pkg-config --exists libargon2:install_system_pkg argon2"
)

# ================= 主流程 =================
check_environment() {
    info "正在检查系统环境..."
    
    # 网络检查
    if ! curl -s --retry 3 --connect-timeout 5 https://registry.npmjs.org >/dev/null; then
        warning "网络连接检测失败，建议："
        echo "1. 检查代理或网络设置"
        echo "2. 尝试使用镜像源：npm config set registry=https://registry.npmmirror.com"
        read -rp "是否继续？[y/N] " answer
        [[ "$answer" =~ [Yy] ]] || exit 1
    fi

    # 处理所有依赖
    for dep in "${DEPENDENCIES[@]}"; do
        IFS=':' read -r name check_cmd installer <<< "$dep"
        if [ "$check_cmd" = "check_nodejs" ]; then
            eval "$check_cmd"
        else
            check_dependency "$name" "$check_cmd" "$installer"
        fi
    done
}

build_project() {
    # 前端构建
    (
        info "进入前端目录: ${FRONTEND_DIR}"
        cd "${FRONTEND_DIR}" || { error "前端目录不存在"; exit 1; }
        
        info "安装npm依赖..."
        npm install --progress=true && success "前端依赖安装成功" || {
            error "前端依赖安装失败"
            exit 1
        }
    )

    # 后端构建
    (
        echo -e "\n${BOLD}----------------------------------------${RESET}"
        info "进入后端目录: ${BACKEND_DIR}"
        cd "${BACKEND_DIR}" || { error "后端目录不存在"; exit 1; }
        
        info "清理旧构建..."
        make clean && success "清理完成" || warning "清理旧构建失败"
        
        info "编译后端..."
        make && success "编译成功" || {
            error "编译失败"
            exit 1
        }
    )
}

# ================= 主函数 =================
main() {
    check_environment
    success "所有依赖检查通过"
    
    echo -e "\n${BOLD}================= 开始构建 ================="
    build_project
    
    echo -e "\n${BOLD}${GREEN}=============== 构建完成 ===============${RESET}"
    warning "请先配置您的云服务器ip以实现远程访问网站，或设置ip为'127.0.0.1'供本地访问"
    echo -e "${BOLD}配置文件所在路径:${RESET}"
    echo -e "${YELLOW}- $CONFIG_FILE${RESET}"
    echo -e "${BOLD}${GREEN}========================================${RESET}"
    echo -e "注意完成配置后再启动命令："
    echo -e "${BOLD}${YELLOW}./run_project.sh${RESET}"
}

# 执行入口
main